/*
 * https://github.com/stefanpenner/es6-promise
 *require('es6-promise').polyfill();
 */
// import extendOriginObject from './utils/extend-origin-object.js';
import config from './config/config'
import Artery from './utils/Artery.js'
import { formatDate } from './components/form/date-picker/util'
/*
 * import commonPlugin from './utils/commonPlugin';
 * import Vue from 'vue';
 *Vue.use(commonPlugin);
 */
// basic start
import panel from './components/basic/panel/index.vue'
import text from './components/basic/text/index.vue'
import link from './components/basic/link/index.vue'
import title from './components/basic/title/index.vue'
import image from './components/basic/image/index.vue'
import button from './components/basic/button/index.vue'
import icon from './components/basic/icon/index.vue'
import iframe from './components/basic/iframe/index.vue'
import col from './components/basic/col/index.vue'
import row from './components/basic/row/index.vue'
// basic end

// data start
import badge from './components/data/badge/index.vue'
import card from './components/data/card/index.vue'
import progress from './components/data/progress/index.vue'
import report from './components/data/report/index.vue'
import table from './components/data/table/index.vue'
import tableColumn from './components/data/table/table-column/index.js'
import tag from './components/data/tag/index.vue'
import timeline from './components/data/timeline/index.vue'
import timelineItem from './components/data/timeline/timeline-item/index.vue'
import customFilter from './components/data/table/customfilter/index.vue'
import circleProgress from './components/data/circle-progress/index.vue'
// data end

// form start
import cascader from './components/form/cascader/index.vue'
import checkbox from './components/form/checkbox/index.vue'
import checkboxGroup from './components/form/checkbox-group/index.vue'
import datePicker from './components/form/date-picker/index.js'
import timePicker from './components/form/time-picker/index.js'
import form from './components/form/form/index.vue'
import formItem from './components/form/form-item/index.vue'
import input from './components/form/input/index.vue'
import inputNumber from './components/form/input-number/index.vue'
import radio from './components/form/radio/index.vue'
import radioGroup from './components/form/radio-group/index.vue'
import rate from './components/form/rate/index.vue'
import select from './components/form/select/index.vue'
import selectTree from './components/form/select-tree/index.vue'
import option from './components/form/select/option/index.vue'
import optionGroup from './components/form/select/option-group/index.vue'
import slider from './components/form/slider/index.vue'
import $switch from './components/form/switch/index.vue'
import textarea from './components/form/textArea/index.vue'
import transfer from './components/form/transfer/index.js'
import upload from './components/form/upload/index.vue'
import organTree from './components/form/organ-tree/index.vue'
import autoComplete from './components/form/auto-complete/index.vue'
import inputMoney from './components/form/input-money/index.vue'
// form end

// region start
import regionLayout from './components/layout/region-layout/index.vue'
import regionNorth from './components/layout/region-layout/region-north/index.vue'
import regionSouth from './components/layout/region-layout/region-south/index.vue'
import regionCenter from './components/layout/region-layout/region-center/index.vue'
import regionWest from './components/layout/region-layout/region-west/index.vue'
import regionEast from './components/layout/region-layout/region-east/index.vue'
import buttonGroup from './components/layout/button-group/index.vue'
import floatLayout from './components/layout/float-layout/index.vue'
// layout end

// navigation start
import breadcrumb from './components/navigation/breadcrumb/index.vue'
import dropdown from './components/navigation/dropdown/index.vue'
import dropdownItem from './components/navigation/dropdown/dropdown-item/index.vue'
import dropdownMenu from './components/navigation/dropdown/dropdown-menu/index.vue'
import dropdownPanel from './components/navigation/dropdown/dropdown-panel/index.vue'
import menu from './components/navigation/menu/index.vue'
import submenu from './components/navigation/menu/submenu/index.vue'
import menuItem from './components/navigation/menu/menu-item/index.vue'
import menuGroup from './components/navigation/menu/menu-group/index.vue'
import steps from './components/navigation/steps/index.vue'
import stepsItem from './components/navigation/steps/steps-item/index.vue'
import tabs from './components/navigation/tabs/index.js'
import tabpane from './components/navigation/tabs/tabpane/index.vue'
import tabspace from './components/navigation/tabs/tabspace/index.vue'
import splitableTabs from './components/navigation/tabs/index-splitable.js'
import tree from './components/navigation/tree/index.vue'
// navigation end

// notice start
import $alert from './components/notice/alert/index.vue'
import message from './components/notice/message/index.js'
import notice from './components/notice/notice/index.js'
import poptip from './components/notice/poptip/index.vue'
import tooltip from './components/notice/tooltip/index.vue'
// notice end

// other start
// import accordion from './components/other/accordion/index.vue'
// import editor from './components/other/editor/index.vue'
// import moveView from './components/other/move-view/index.vue'
import scroll from './components/other/scroll/index.vue'
// import swiper from './components/other/swiper/index.vue'
import showMore from './components/other/show-more/index.vue'
import mendPhoto from './components/other/mend-photo/index.vue'
// other end

// pagination start
import pagination from './components/pagination/pagination/index.vue'
// pagination end

// popup start
import modal from './components/popup/modal/index'
// popup end

// tools start
import affix from './components/tools/affix/index.vue'
import backTop from './components/tools/back-top/index.vue'
import colorPicker from './components/tools/color-picker/index.vue'
import divider from './components/tools/divider/index.vue'
import loadingBar from './components/tools/loading-bar/index.js'
import spin from './components/tools/spin/index.js'
// tools end

// auth start
import captchaSlide from './components/captcha/slide/index.vue'
import captchaString from './components/captcha/string/index.vue'
// auth end

import locale from './locale/index'
if (!Artery.isServer) {
window.requestAnimationFrame = window.requestAnimationFrame || function (fn) {
  return setTimeout(fn, 1000 / 60)
} // 兼容IE9
window.cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout // 兼容IE9
if (!String.prototype.trim) { // 兼容IE9
  String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, '')
    }
  }
}

const components = {
  // basic start
  panel,
  text,
  link,
  title,
  image,
  button,
  icon,
  iframe,
  col,
  row,
  // basic end

  // data start
  badge,
  card,
  progress,
  report,
  table,
  tableColumn,
  tag,
  timeline,
  timelineItem,
  customFilter,
  circleProgress,
  // data end

  // form start
  cascader,
  checkbox,
  checkboxGroup,
  datePicker,
  timePicker,
  form,
  formItem,
  input,
  inputNumber,
  radio,
  radioGroup,
  rate,
  select,
  selectTree,
  option,
  optionGroup,
  slider,
  $switch,
  textarea,
  transfer,
  upload,
  organTree,
  autoComplete,
  inputMoney,
  // form end

  // region start
  regionLayout,
  regionNorth,
  regionSouth,
  regionCenter,
  regionWest,
  regionEast,
  buttonGroup,
  floatLayout,
  // layout end

  // navigation start
  breadcrumb,
  dropdown,
  dropdownItem,
  dropdownMenu,
  dropdownPanel,
  menu,
  submenu,
  menuItem,
  menuGroup,
  steps,
  stepsItem,
  tabs,
  tabpane,
  tabspace,
  splitableTabs,
  tree,

  // navigation end

  // notice start
  $alert,
  message,
  notice,
  poptip,
  tooltip,
  // notice end

  // other start
  scroll,
  showMore,
  mendPhoto,
  // other end

  // pagination start
  pagination,
  // pagination end

  // popup start
  modal,
  // popup end

  // tools start
  affix,
  backTop,
  colorPicker,
  divider,
  loadingBar,
  spin,
  // tools end

  // auth start
  captchaSlide,
  captchaString
  // auth end
}

const _artery = {
  ...components
}

// 安装
const install = function (Vue, opts = {}) {
  // debugger
  if (install.installed) {
    return
  }
  locale.use(opts.locale)
  locale.i18n(opts.i18n)
  var i = 0
  // 注册组件
  Object.keys(_artery).forEach(key => {
    i++
    const pattern = /([A-Z])|^(\$)/gm
    let _key = key
    // 大写转-小写
    _key = _key.replace(pattern, function (a, b, c, d, e) {
      // ==$ 表示是因为组件是关键词，所以多加了标识符$
      return a == '$' ? '' : '-' + a.toLowerCase()
    })
    Vue.component(config.prefix + '-' + _key, _artery[key])
    /*
     * 注册成atyButton的形式, 否则按需引入 import解构不支持横线方式
     * 输出日志
     */
    Artery.consoleLog(config.showLog, '【' + config.prefix + '-' + _key + '】组件注册成功，可以开始使用！')
  })
  Vue.prototype.$Message = message
  Vue.prototype.$Notice = notice
  Vue.prototype.$Spin = spin
  Vue.prototype.$LoadingBar = loadingBar
  Vue.prototype.$Modal = modal
  Vue.prototype.dateFormat = formatDate
  // table中的fomatter属性会用到
  Vue.prototype.df = function(formatter) {
    return function (value) {
      return formatDate(value, formatter)
    }
  }
  if (opts.locale) {
    Vue.prototype.$Locale = locale
  }
  if (Artery.isServer) {
    global.Artery = Artery
  } else {
  window.Artery = Artery
  }


  // Vue.prototype.$http = $http //
  /*
   * Vue.prototype.loadPageData = Artery.loadPageData; // 用例, 这么用会导致loadPageData中的this指向了vue而非Artery
   * Vue.prototype.loadCode = Artery.loadCode; // 下拉列表， checkbox-group radio-group
   */
  // Vue.prototype.resolveObj = Artery.resolveObj //  用例
  // console.log(i)
  /**
   * @description   inherit vue.prototype.$Message
   */
}

// auto install
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue)
}

if (!Object) {
  window.Object = {}
}
/*
 * 不知道为啥有的人环境上还是有问题，强制兼容一下吧。。。。
 *console.log(Object.values);
 */
if (!Object.values) {
  // console.log("浏览器不支持Object.values, 采用Artery的实现")
  if (!Object.values) {
    Object.values = function (obj) {
      if (obj !== Object(obj)) { throw new TypeError('Object.values called on a non-object') }
      var val = []; var key
      for (key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          val.push(obj[key])
        }
      }
      return val
    }
  }
}
if (!Object.keys) {
  console.log('浏览器不支持Object.keys, 采用Artery的实现')
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty
    var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString')
    var dontEnums = [
      'toString',
      'toLocaleString',
      'valueOf',
      'hasOwnProperty',
      'isPrototypeOf',
      'propertyIsEnumerable',
      'constructor'
    ]
    var dontEnumsLength = dontEnums.length

    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object')

      var result = []

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop)
      }

      if (hasDontEnumBug) {
        for (var i = 0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i])
        }
      }
      return result
    }
  })()
};

const API = {
  version: process.env.VERSION, // eslint-disable-line no-undef
  locale: locale.use,
  i18n: locale.i18n,
  install,
  /*
   * Circle,
   * Switch,
   */
  ...components
}

API.lang = (code) => {
  const langObject = window['artery-ui/locale'].default
  if (code === langObject.i.locale) {
    locale.use(langObject)
  } else {
    console.log(`The ${code} language pack is not loaded.`) // eslint-disable-line no-console
  }
}
export default API
